#include <stdio.h>
/**
 * 宏定义
 *
 * 宏 、 带参数宏
 * # 吧宏参数变成字符串 
 * ## 吧两个宏参数粘贴在一起 可以动态的构造函数名称
 * 当宏参数是另一个宏时  宏定义里有用 # ##的地方 宏参数不会展开
 *
 * ===常见问题=======
 * 带参数宏 传入 ++i 的参数 
 * ==========
 */

/**
 * ## # 的一些应用特例
 *  1、合并匿名变量名
 *
#define __ANONYMOUS1(type,var,line) type var##line
#define __ANONYMOUS0(type,line) __ANONYMOUS1(type,_anonymous,line)
#define ANONYMOUS(type) __ANONYMOUS0(type,__LINE__)
第一层：ANONYMOUS(static int);  -->  __ANONYMOUS0(static int, __LINE__); 
第二层：                        -->  ___ANONYMOUS1(static int, _anonymous, 70); 
第三层：                        -->  static int  _anonymous70; 
即每次只能解开当前层的宏，所以__LINE__在第二层才能被解开； 
*/



/**
 * 加一层转换宏  展开 # ## 宏参数
 * 每次只能解开当前层的宏  
 *
#define A 2
#define _STR(s) #s
#define STR(s) _STR(s)
#define _CONS(a,b) (int)(a##e##b)
#define CONS(a,b) _CONS(a,b)
void main()
{
    printf("%s\n",STR(A));
    printf("%d\n",CONS(A,A));
}
*/


/**
 * 使用 ## 动态构造函数名
 *

#define SORT(x) sort_function##x
void main()
{
    char a;
    int e,e2;
    SORT(3)(a,e,e2); // # sort_function3(a,e,e2)
}
*/

/**
 * 宏参数是另一个宏
 * ##　＃　不展开
 * 解决办法 ：加一层转换宏
 * ##拼接后 当成了函数 没有函数 会报错  可参考上面的 用 ## 动态构造函数名
 *
#define A (2)
#define STR(s)  #s
#define CONS(a,b) (char*)(a##e##b)

int main()
{
    printf(STR(A)); // = printf("A");

    //printf("%s\n",CONS(A,A)); // = printf("%s\n",AeA);  报错  没有这个函数名
    return 0;
}

*/



/**
 *
 * # 和 ## 
 *
#define STR(s) #s
#define CONS(a,b) (int)(a##e##b)

int main()
{
    printf(STR(fadffda));
    printf("\n%d\n",CONS(2,3));
    return 0;
}

*/
